#include "widget.h"
#include "ui_widget.h"
#include <unistd.h>
#define INCREMENT 3  // 温度每升高/降低 1°，y轴坐标的增量
#define POINT_RADIUS 3 // 曲线描点的大小(点的半径)
#define TEXT_OFFSET_X 12  // 文字偏移
#define TEXT_OFFSET_Y 12

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    ui->lineEdit->setReadOnly(false);  // 确保不是只读
    ui->lineEdit->setEnabled(true);    // 确保不是禁用状态
    ui->lineEdit->setInputMethodHints(Qt::ImhPreferLatin|Qt::ImhPreferLowercase|Qt::ImhNoAutoUppercase);
    //设置窗口边框
    setWindowFlag(Qt::FramelessWindowHint);
    //设置固定窗口大小
    setFixedSize(width(),height());

    //构建右键菜单
    mExitMenu = new QMenu(this);
    mExitAct = new QAction();
    mExitAct->setText("退出");
    mExitMenu->addAction(mExitAct);
    connect(mExitAct,&QAction::triggered,this,[=]{
        qApp->exit();
    });

     mNetworkAccessManager = new QNetworkAccessManager(this);
     connect(mNetworkAccessManager,&QNetworkAccessManager::finished,this,&Widget::onReplied);

    // 直接在构造中，请求天气数据
    //北城市编码 ：101010100；
    getWeatherInfo("101010100");

    // 将控件放到数组里面，方便使用循环进行处理
    // 星期
    mweekList<<ui->lblWeek0_4<<ui->lblWeek1_4<<ui->lblWeek2_4<<ui->lblWeek3_4<<ui->lblWeek4_4<<ui->lblWeek5_4;
    // 日期
    mdateList<<ui->lblDate0_4<<ui->lblDate1_4<<ui->lblDate2_4<<ui->lblDate3_4<<ui->lblDate4_4<<ui->lblDate5_4;
    // 天气类型
    mtypeList<<ui->lblType0_4<<ui->lblType1_4<<ui->lblType2_4<<ui->lblType3_4<<ui->lblType4_4<<ui->lblType5_4;
    // 天气类型图标
    mtypeIconList<<ui->lblTypeIcon0_4<<ui->lblTypeIcon1_4<<ui->lblTypeIcon2_4<<ui->lblTypeIcon3_4<<ui->lblTypeIcon4_4<<ui->lblTypeIcon5_4;
    // 天气污染指数
    mAqiList<<ui->lblQuality0_4<<ui->lblQuality1_4<<ui->lblQuality2_4<<ui->lblQuality3_4<<ui->lblQuality4_4<<ui->lblQuality5_4;
    // 风向
    mfxList<<ui->lblFx0_4<<ui->lblFx1_4<<ui->lblFx2_4<<ui->lblFx3_4<<ui->lblFx4_4<<ui->lblFx5_4;
    // 风力
    mflList<<ui->lblFl0_4<<ui->lblFl1_4<<ui->lblFl2_4<<ui->lblFl3_4<<ui->lblFl4_4<<ui->lblFl5_4;


    // 天气类型图标路径
    //根据keys,设置icon的路径
    mTypeMap.insert("暴雪",":/Weather_Icon/BaoXue.png");
    mTypeMap.insert("暴雨",":/Weather_Icon/BaoYu.png");
    mTypeMap.insert("暴雨到大暴雨",":/Weather_Icon/BaoYuDaoDaBaoYu.png");
    mTypeMap.insert("大暴雨",":/Weather_Icon/DaBaoYu.png");
    mTypeMap.insert("大暴雨到特大暴雨",":/Weather_Icon/DaBaoYuDaoTeDaBaoYu.png");
    mTypeMap.insert("大到暴雪",":/Weather_Icon/DaDaoBaoXue.png");
    mTypeMap.insert("大雪",":/Weather_Icon/DaXue.png");
    mTypeMap.insert("大雨",":/Weather_Icon/DaYu.png");
    mTypeMap.insert("冻雨",":/Weather_Icon/DongYu.png");
    mTypeMap.insert("多云",":/Weather_Icon/DuoYun.png");
    mTypeMap.insert("浮沉",":/Weather_Icon/FuChen.png");
    mTypeMap.insert("雷阵雨",":/Weather_Icon/LeiZhenYu.png");
    mTypeMap.insert("雷阵雨伴有冰雹",":/Weather_Icon/LeiZhenYuBanYouBingBao.png");
    mTypeMap.insert("霾",":/Weather_Icon/Mai.png");
    mTypeMap.insert("强沙尘暴",":/Weather_Icon/QiangShaChenBao.png");
    mTypeMap.insert("晴",":/Weather_Icon/Qing.png");
    mTypeMap.insert("沙尘暴",":/Weather_Icon/ShaChenBao.png");
    mTypeMap.insert("特大暴雨",":/Weather_Icon/TeDaBaoYu.png");
    mTypeMap.insert("undefined",":/Weather_Icon/WuData.png");
    mTypeMap.insert("雾",":/Weather_Icon/Wu.png");
    mTypeMap.insert("小到中雪",":/Weather_Icon/XiaoDaoZhongXue.png");
    mTypeMap.insert("小到中雨",":/Weather_Icon/XiaoDaoZhongYu.png");
    mTypeMap.insert("小雪",":/Weather_Icon/XiaoXue.png");
    mTypeMap.insert("小雨",":/Weather_Icon/XiaoYu.png");
    mTypeMap.insert("雪",":/Weather_Icon/Xue.png");
    mTypeMap.insert("扬沙",":/Weather_Icon/YangSha.png");
    mTypeMap.insert("阴",":/Weather_Icon/Yin.png");
    mTypeMap.insert("雨",":/Weather_Icon/Yu.png");
    mTypeMap.insert("雨夹雪",":/Weather_Icon/YuJiaXue.png");
    mTypeMap.insert("阵雪",":/Weather_Icon/ZhenXue.png");
    mTypeMap.insert("阵雨",":/Weather_Icon/ZhenYu.png");
    mTypeMap.insert("中到大雪",":/Weather_Icon/ZhongDaoDaXue.png");
    mTypeMap.insert("中到大雨",":/Weather_Icon/ZhongDaoDaYu.png");
    mTypeMap.insert("中雪",":/Weather_Icon/ZhongXue.png");
    mTypeMap.insert("中雨",":/Weather_Icon/ZhongYu.png");

    //给标签添加时间过滤器
    //参数指定为this 也就是当前窗口对象
    ui->lblHighCurve_4->installEventFilter(this);
    ui->lblLowCurve_4->installEventFilter(this);

    //创建表格设置ID为主键自动增加
    QString str="CREATE TABLE IF NOT EXISTS tianqicity ("
                  "id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, "
                  "id_1 INTEGER,"
                  "name VARCHAR(255)"
                  ");";

    db = QSqlDatabase::addDatabase("QSQLITE");
    //设置数据库文件路径
    db.setDatabaseName("./tianqi.db");
    query=QSqlQuery("./tianqi.db");
    //打开数据库
    if(!db.open())
    {
       qDebug()<<"数据库打开失败" <<db.lastError().text();
    }
    if(query.exec(str) == false)
        {
            qDebug()<<"指向SQL语句失败！"<<str<<db.lastError().text();
        }
    db.close();
    QPainter painter_1(this);
    painter_1.drawPixmap(0,0,width(),height(),QPixmap(":/Weather_Icon/backboard(1).png"));
    sleep(1);

}

Widget::~Widget()
{
    delete mNetworkAccessManager;
    delete mExitMenu;
    delete mExitAct;
    delete ui;
}


//重写父类的虚函数

void Widget::on_pushButton_clicked()
{
    this->close();
}

void Widget::contextMenuEvent(QContextMenuEvent *event)
{
    //弹出右键菜单
    mExitMenu->exec(QCursor::pos());
}

void Widget::getWeatherInfo(QString cityCode)
{
    QUrl url("http://t.weather.itboy.net/api/weather/city/"+cityCode);
    mNetworkAccessManager->get(QNetworkRequest(url));
}

//数据解析 解析JSON
void Widget::parseJson(QByteArray &byteArray)
{
    QJsonParseError err;
    QJsonDocument doc =  QJsonDocument::fromJson(byteArray,&err);
    if(err.error != QJsonParseError::NoError)
    {
        return;
    }
    QJsonObject rootObj = doc.object();
    qDebug()<<rootObj.value("message").toString();

    //1、解析时间和城市
    mToday.date = rootObj.value("date").toString();
    mToday.city =  rootObj.value("cityInfo").toObject().value("city").toString();

    //2、解析yestoday
    QJsonObject objdata = rootObj.value("data").toObject();

    QJsonObject objyesterday = objdata.value("yesterday").toObject();
    mDay[0].week = objyesterday.value("week").toString();
    mDay[0].date = objyesterday.value("ymd").toString();
    mDay[0].type = objyesterday.value("type").toString();

    QString s;
    s=objyesterday.value("high").toString().split(" ").at(1);// 18°
    s=s.left(s.length()-1);// 18
    mDay[0].high=s.toInt();


    s=objyesterday.value("low").toString().split(" ").at(1);// 6°
    s=s.left(s.length()-1);// 6
    mDay[0].low=s.toInt();
    //风向风力
    mDay[0].fx = objyesterday.value("fx").toString();
    mDay[0].fl = objyesterday.value("fl").toString();

    //污染指数
    mDay[0].aqi = objyesterday.value("aqi").toDouble();

    //3、解析forcast中五天的数据
    QJsonArray forecastArray = objdata.value("forecast").toArray();
    for(int i=0 ; i < 5;i++)
    {
        QJsonObject objForecast = forecastArray[i].toObject();
        mDay[i+1].week = objForecast.value("week").toString();
        mDay[i+1].date = objForecast.value("ymd").toString();

        //天气类型
        mDay[i+1].type = objForecast.value("type").toString();

        //高温低温
        s=objForecast.value("high").toString().split(" ").at(1);// 18°
        s=s.left(s.length()-1);// 18
        mDay[i+1].high=s.toInt();


        s=objForecast.value("low").toString().split(" ").at(1);// 6°
        s=s.left(s.length()-1);// 6
        mDay[i+1].low=s.toInt();

        //风向风力
        mDay[i+1].fx = objForecast.value("fx").toString();
        mDay[i+1].fl = objForecast.value("fl").toString();

        //污染指数
        mDay[i+1].aqi = objForecast.value("aqi").toDouble();
        qDebug()<<mDay[i].high<<mDay[i].low;
    }
    //4、解析今天的数据
    mToday.ganmao = objdata.value("ganmao").toString();

    mToday.wendu = objdata.value("wendu").toString();
    mToday.shidu = objdata.value("shidu").toString();
    mToday.pm25 = objdata.value("pm25").toInt();
    mToday.quality = objdata.value("quality").toString();

    //forcast中第一个数据元素也是今天的数据
    mToday.fl = mDay[1].fl;
    mToday.fx =mDay[1].fx;
    mToday.type = mDay[1].type;
    mToday.high =mDay[1].high;
    mToday.low =mDay[1].low;
    qDebug()<<mToday.wendu<<mToday.low<<mToday.high;
    //6、更新UI
    updataUI();

    //7. 绘制曲线
    ui->lblHighCurve_4->update();//触发绘画事件
    ui->lblLowCurve_4->update();


}

void Widget::updataUI()
{
    // 1、更新日期和城市
    ui->lbDate->setText(QDateTime::fromString(mToday.date,"yyyyMMdd").toString("yyyy/MM/dd")+" "+mDay[1].week);
    ui->lbCity_4->setText(mToday.city);// 城市

    //2、更新今天
    ui->lbTypeIcon_4->setPixmap(mTypeMap[mToday.type]);
    ui->lbTypeIcon_4->setScaledContents(true);
    ui->lbTemp_4->setText(mToday.wendu + "℃");
    ui->lbType_4->setText(mToday.type);
    ui->lbLowHigh_4->setText(QString::number(mToday.low) + "~" + QString::number(mToday.high) + "℃");
    ui->lbGaoMao_4->setText("感冒指数：" + mToday.ganmao);
    ui->lbWindFl_4->setText(mToday.fl);
    ui->lbWindFx_4->setText(mToday.fx);
    ui->lbPm25_4->setText(QString::number(mToday.pm25));

    ui->lbShiDu_4->setText(mToday.shidu);
    ui->lblQuality_4->setText(mToday.quality);

    ui->lbWindIcon_4->setPixmap(QPixmap(":/wind.png"));
    ui->lblQualityIcon_4->setPixmap(QPixmap(":/aqi.png"));
    ui->lbPm25Icon_4->setPixmap(QPixmap(":/pm25.png"));
    ui->lbShiDuIcon_4->setPixmap(QPixmap(":/humidity.png"));
    //2. 更新6天
    for (int i=0;i<6;i++) {
        // 日期
        mweekList[i]->setText("周"+mDay[i].week.right(1));// mDay[i].week="星期x"
            ui->lblWeek0_4->setText("昨天");
            ui->lblWeek1_4->setText("今天");
            ui->lblWeek2_4->setText("明天");

            // 时间
            QStringList ymdList=mDay[i].date.split("-");// mDay[i].date="2023-03-26"
            mdateList[i]->setText(ymdList[1]+"/"+ymdList[2]);
            // 天气类型
            mtypeList[i]->setText(mDay[i].type);
            mtypeIconList[i]->setPixmap(mTypeMap[mDay[i].type]);
            mtypeIconList[i]->setScaledContents(true);
            // 空气质量
            if(mDay[i].aqi >= 0 && mDay[i].aqi <= 50){
                mAqiList[i]->setText("优");
                mAqiList[i]->setStyleSheet("background-color:rgb(121,184,0);");
            }else if(mDay[i].aqi > 50 && mDay[i].aqi <= 100){
                mAqiList[i]->setText("良");
                mAqiList[i]->setStyleSheet("background-color:rgb(255,187,23);");
            }else if(mDay[i].aqi > 100 && mDay[i].aqi <= 150){
                mAqiList[i]->setText("轻度");
                mAqiList[i]->setStyleSheet("background-color:rgb(255,87,97);");
            }else if(mDay[i].aqi > 150 && mDay[i].aqi <= 200){
                mAqiList[i]->setText("中度");
                mAqiList[i]->setStyleSheet("background-color:rgb(235,17,27);");
            }else if(mDay[i].aqi > 200 && mDay[i].aqi <= 250){
                mAqiList[i]->setText("重度");
                mAqiList[i]->setStyleSheet("background-color:rgb(170,0,0);");
            }else {
                mAqiList[i]->setText("严重");
                mAqiList[i]->setStyleSheet("background-color:rgb(110,0,0);");
            }
            // 风向
            mfxList[i]->setText(mDay[i].fx);
            mflList[i]->setText(mDay[i].fl);//风力

    }
}

bool Widget::eventFilter(QObject *watched, QEvent *event)
{
    if(watched == ui->lblHighCurve_4 && event->type() == QEvent::Paint)
    {
        paintHighCurve();
    }
    if(watched == ui->lblLowCurve_4 && event->type() == QEvent::Paint)
    {
        paintLowcurve();
    }

    return QWidget::eventFilter(watched,event);
}

void Widget::paintHighCurve()
{
    QPainter painter(ui->lblHighCurve_4);// 画家类
    // 抗锯齿
    painter.setRenderHint(QPainter::Antialiasing,true);
    // 1. 获取x轴坐标
    int pointX[6]={0};
    for(int i=0;i<6;i++){
        pointX[i]=mweekList[i]->pos().x()+(mweekList[i]->width()/4);
    }
    // 2. 获取y轴坐标
    int tempSum=0;//总和
    int tempAverage=0;//平均
    for(int i=0;i<6;i++){
        tempSum+=mDay[i].high;
    }
    tempAverage=tempSum/6; // 最高温的平均值
    // 计算y轴坐标
    int pointY[6]={0};
    int yCenter = ui->lblHighCurve_4->height()/2;
    for(int i=0;i<6;i++){
        pointY[i]=yCenter - ((mDay[i].high-tempAverage)*INCREMENT);
    }

    // 3. 开始绘制
    // 3.1 初始化画笔相关
    QPen pen=painter.pen();
    pen.setWidth(1);    //设置画笔的宽度
    pen.setColor(QColor(255,170,0)); //设置画笔的颜色
    painter.setPen(pen);//给画家设置画笔
    painter.setBrush(QColor(255,170,0));//设置画刷的颜色-内部填充的颜色
    // 3.2 画点、画文字
    for(int i=0;i<6;i++){
        // 显示点
        painter.drawEllipse(QPoint(pointX[i],pointY[i]),POINT_RADIUS,POINT_RADIUS);
        // 显示温度
        painter.drawText(pointX[i]-TEXT_OFFSET_X,pointY[i]-TEXT_OFFSET_X,
                         QString::number(mDay[i].high));
    }
    // 3.3绘制曲线
    for(int i=0;i<6-1;i++){
        if(i == 0){
            pen.setStyle(Qt::DotLine);//虚线
            painter.setPen(pen);
        }else{
            pen.setStyle(Qt::SolidLine);//虚线
            painter.setPen(pen);
        }
        painter.drawLine(pointX[i],pointY[i],pointX[i+1],pointY[i+1]);
    }
}

void Widget::paintLowcurve()
{
    QPainter painter(ui->lblLowCurve_4);// 画家类
    // 抗锯齿
    painter.setRenderHint(QPainter::Antialiasing,true);
    // 1. 获取x轴坐标
    int pointX[6]={0};
    for(int i=0;i<6;i++){
        pointX[i]=mweekList[i]->pos().x()+(mweekList[i]->width()/4);
    }
    // 2. 获取y轴坐标
    int tempSum=0;//总和
    int tempAverage=0;//平均
    for(int i=0;i<6;i++){
        tempSum+=mDay[i].low;
    }
    tempAverage=tempSum/6; // 最高温的平均值
    // 计算y轴坐标
    int pointY[6]={0};
    int yCenter = ui->lblLowCurve_4->height()/2;
    for(int i=0;i<6;i++){
        pointY[i]=yCenter - ((mDay[i].low-tempAverage)*INCREMENT);
    }

    // 3. 开始绘制
    // 3.1 初始化画笔相关
    QPen pen=painter.pen();
    pen.setWidth(1);    //设置画笔的宽度
    pen.setColor(QColor(0,255,255)); //设置画笔的颜色
    painter.setPen(pen);//给画家设置画笔
    painter.setBrush(QColor(0,255,255));//设置画刷的颜色-内部填充的颜色
    // 3.2 画点、画文字
    for(int i=0;i<6;i++){
        // 显示点
        painter.drawEllipse(QPoint(pointX[i],pointY[i]),POINT_RADIUS,POINT_RADIUS);
        // 显示温度
        painter.drawText(pointX[i]-TEXT_OFFSET_X,pointY[i]-TEXT_OFFSET_X,
                         QString::number(mDay[i].low));
    }
    // 3.3绘制曲线
    for(int i=0;i<6-1;i++){
        if(i == 0){
            pen.setStyle(Qt::DotLine);//虚线
            painter.setPen(pen);
        }else{
            pen.setStyle(Qt::SolidLine);//虚线
            painter.setPen(pen);
        }
        painter.drawLine(pointX[i],pointY[i],pointX[i+1],pointY[i+1]);
    }
}

void Widget::onReplied(QNetworkReply *reply)
{
    qDebug()<<"opRplied success";
    int status_code = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();

    qDebug()<<"operation:"<<reply->operation();
    qDebug()<<"status code :"<<status_code;
    qDebug()<<"url:"<<reply->url();
    qDebug()<<"raw header:"<<reply->rawHeaderList();

    //  先检查请求是否出错
    if (reply->error() != QNetworkReply::NoError|| status_code != 200) {
        qDebug() << "[请求错误] 错误码：" << reply->error();
        qDebug() << "[请求错误] 错误描述：" << reply->errorString();
        QMessageBox::warning(this,"天气","请求数据失败",QMessageBox::Ok);
        return;
    }
    else
    {
        QByteArray byteArray = reply->readAll();
        qDebug()<<"read all:"<<byteArray.data();
        parseJson(byteArray);
    }
    reply->deleteLater(); // 记得释放 reply，避免内存泄漏
}



void Widget::on_pushButton_2_clicked()
{
    db.open();
    QString name = ui->lineEdit->text();
    QString str = QString("SELECT * FROM tianqicity WHERE name = '%1' LIMIT 1").arg(name);
    query.exec(str);
    qDebug()<<name;

    if(query.next())
    {
       getWeatherInfo(query.value("id_1").toString());
    }
    else
    {
        QMessageBox::about(this,"提示","没有查询到该城市");
    }
    db.close();
}

